#pragma once

#include <cstdint>
#include "ImportExport.h"

namespace FTLib
{

	enum class PixelType
	{
		GrayFloat32,
		GrayDouble64,
		ComplexFloat32,
		ComplexDouble64,
		Gray16,
		Gray8
	};

	struct BitmapLockInfo
	{
		void*				ptrData;
		void*				ptrDataRoi;
		std::uint32_t		pitch;
		std::uint64_t		size;
	};

	class IBitmapData
	{

	public:
		virtual PixelType			GetPixelType() const = 0;
		virtual std::uint32_t		GetWidth() const = 0;
		virtual std::uint32_t		GetHeight() const = 0;

		virtual BitmapLockInfo	Lock() = 0;
		virtual void Unlock() = 0;
	};


	const uint16_t DATASTOREKEY_SEMANTICS = 1;	// Type: uint16_t
	const uint16_t DS_SEMANTICS_IMAGE = 0;
	const uint16_t DS_SEMANTICS_FOURIERTRANSFORMED = 1;

	const uint16_t DATASTOREKEY_FOURIERTRANSFORMED_LAYOUT = 800;
	const uint8_t DS_FOURIERTRANSFORMED_LAYOUT_FULL_REAL = 1;
	const uint8_t DS_FOURIERTRANSFORMED_LAYOUT_FULL_IMAG = 2;
	const uint8_t DS_FOURIERTRANSFORMED_LAYOUT_FULL_REALIMAGINTERLEAVED = 3;
	const uint8_t DS_FOURIERTRANSFORMED_LAYOUT_FULL_FFTWPACKED = 8;
	const uint8_t DS_FOURIERTRANSFORMED_LAYOUT_FULL_IPPPACKED = 16;

	class ITinyDataStore
	{
	public:
		enum class AddValueRetCode
		{
			Success_Added,
			Success_Updated,
			Failure_CapacityExceeded,
			Failure_ItemsLengthTooLarge
		};

		virtual bool	GetValue(uint16_t key, void* ptrData, uint8_t sizeData, uint8_t* ptrSizeRequired) const = 0;
		virtual AddValueRetCode AddOrSetValue(uint16_t key, void* ptrData, uint8_t sizeData) = 0;

		bool GetValueInt32(uint16_t key, int& value) { return this->GetValue(key, &value, sizeof(int32_t), nullptr); }
		bool GetValueUInt8(uint16_t key, std::uint8_t& value) { return this->GetValue(key, &value, sizeof(std::uint8_t), nullptr); }
		bool GetValueUInt16(uint16_t key, std::uint16_t& value) { return this->GetValue(key, &value, sizeof(std::uint16_t), nullptr); }
		AddValueRetCode AddOrSetValueUint8(uint16_t key, uint8_t value) { return this->AddOrSetValue(key, &value, sizeof(value)); }
		AddValueRetCode AddOrSetValueUint16(uint16_t key, uint16_t value) { return this->AddOrSetValue(key, &value, sizeof(value)); }
	};

	class IRWLock
	{
	public:
		virtual void lock_write() = 0;
		virtual void lock_read() = 0;
		virtual void unlock_write() = 0;
		virtual void unlock_read() = 0;
	};

	class IBitmapData2 : public IRWLock, public ITinyDataStore, public IBitmapData
	{
	};

	std::shared_ptr<FTLib::IBitmapData2> FTLIB_API CreateBitmapStd(FTLib::PixelType pixeltype, std::uint32_t width, std::uint32_t height, std::uint32_t pitch = 0, std::uint32_t extraRows = 0, std::uint32_t extraColumns = 0);

}